/*
 *  liquidity/constraint-layout-manager.vala
 *
 *  Copyright (c) 2008 Patrick Walton <pcwalton@uchicago.edu>
 */

using GLib;
using Gee;

namespace Liquidity {
    public class ConstraintLayoutManager : Object, ILayoutManager {
        private enum ConstraintVariableQuantity {
            X,
            Y,
            W,
            H
        };

        private class ConstraintVariable : Object {
            public ConstraintVariableQuantity quantity;
            public ActorModel model;

            public ConstraintVariable(ConstraintVariableQuantity q, ActorModel
                    m)
            {
                quantity = q;
                model = m;
            }

            public bool equals(ConstraintVariable other)
            {
                return quantity == other.quantity && model == other.model;
            }
        }

        public void invalidate_layout_of_model(ActorModel model)
        {
            /* TODO */
        }

        private void gather_variables_for_constraint(ActorModel model,
                ConstraintAttribute attr, out Constraint a, out Constraint b)
        {
            a = new ConstraintVariable();
            a.model = model;

            switch (attr) {
                case ConstraintAttribute.MIN_X:
                    a.quantity = ConstraintVariableQuantity.X;
                    b = null;
                    break;
                case ConstraintAttribute.MID_X:
                case ConstraintAttribute.MAX_X:
                    a.quantity = ConstraintVariableQuantity.X;
                    b = new ConstraintVariable(model,
                            ConstraintVariableQuantity.WIDTH);
                    break;
                case ConstraintAttribute.WIDTH:
                    a.quantity = ConstraintVariableQuantity.W;
                    b = null;
                    break;
                case ConstraintAttribute.MIN_Y:
                    a.quantity = ConstraintVariableQuantity.Y;
                    b = null;
                    break;
                case ConstraintAttribute.MID_Y:
                case ConstraintAttribute.MAX_Y:
                    a.quantity = ConstraintVariableQuantity.Y;
                    b = new ConstraintVariable(model,
                            ConstraintVariableQuantity.H);
                    break;
                case ConstraintAttribute.HEIGHT:
                    a.quantity = ConstraintVariableQuantity.H;
                    b = null; 
            }

            assert(false);
            b = null;
        }

        private void gather_variables_for_model(ActorModel model,
                HashSet<ConstraintVariable> list)
        {
            ArrayList<Constraint> constraints = model.constraints;
            foreach (Constraint c in constraints) {
                ConstraintVariable a = null, b = null;

                gather_variables_for_constraint(model, attr, out a, out b);
                list.add(a);
                if (b != null)
                    list.add(b);

                gather_variables_for_constraint(
                        );
                /* FIXME: this is all wrong. it's much simpler. instead we just
                   need to make a counter that assigns slots for X, Y, W, H for
                   each actor we might need to consider. we have to allocate
                   all slots before we begin doing anything. then we just go
                   through and generate equations. each set of (actor,
                   quantity) either has an equation number or null. at the end
                   of everything, for each pair that was null, we generate a
                   default equation that simply sets that quantity equal to the
                   value it already has in the model. */

                bool equal = false;

                foreach (ConstraintVariable other in list)
            }
        }

        public void layout_submodels_of_model(ActorModel model)
        {
            HashSet<ConstraintVariable> variables = new
                HashSet<ConstraintVariable>();
            variables.equal_func = ConstraintVariable.equals;

            gather_variables_for_model(model, variables);
        }

        public Size get_preferred_size_of_model(ActorModel model)
        {
            return new Size(0, 0);  /* TODO */
        }
    }
}

